package com.just.fun.thread;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class ThreadPoolTest {
    static AtomicInteger totalRejectedCount = new AtomicInteger(0);
    public static void main(String[] args) {
        //RejectedExecutionHandler rejectedHandler = new ThreadPoolExecutor.AbortPolicy();
        MyRejectHandler rejectedHandler = new MyRejectHandler();
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5,
                20,
                10,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(50),
                new MyThreadFactory(),
                rejectedHandler);
        int n = 100;
        for (int i = 0; i < n; i++) {
            try {
                threadPool.execute(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("执行线程：" + Thread.currentThread().getName() + "活跃执行任务的大致数量:" + threadPool.getActiveCount() + "线程数量:" + threadPool.getPoolSize() + "已完成任务数量:" + threadPool.getCompletedTaskCount());
                        try {
                            Thread.sleep((long) (Math.random() * 1000));
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                });
            } catch (RejectedExecutionException e) {
                System.out.println("任务被拒绝了哦：" + e.getMessage());
            }

        }

        System.out.println("被拒绝的任务数："+totalRejectedCount.get());
    }

    static class MyThreadFactory implements ThreadFactory {
        private AtomicInteger count = new AtomicInteger(0);

        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(r);
            t.setName("myThread-" + count.incrementAndGet());
            return t;
        }
    }

    static class MyRejectHandler implements RejectedExecutionHandler{
        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            System.out.println("自定义处理："+r.toString());
            totalRejectedCount.incrementAndGet();
            //TODO 如何获取业务数据并且重试呢？
            //TODO 可以自定义类实现runnable，这样就可以自定义参数了，可以监控告警以及后续操作，比如重试
        }
    }
}
